package com.jintian.smart.kernel.flowable.config;

import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.delegate.FlowableFunctionDelegate;
import org.flowable.common.engine.impl.el.DefaultExpressionManager;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.ClassUtils;

import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

@Slf4j
public class FlowFunctionRegister implements ApplicationContextAware {
    @Autowired
    SpringProcessEngineConfiguration springProcessEngineConfiguration;

    ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @PostConstruct
    private void init() {
        DefaultExpressionManager manager = (DefaultExpressionManager) springProcessEngineConfiguration.getExpressionManager();
        // TODO 表达数增强支持数组，暂不启用
        // manager.setExpressionFactory(new org.flowable.common.engine.impl.el.FlowableExpressionFactoryExtend());

        List<FlowableFunctionDelegate> list = manager.getFunctionDelegates();
        // 添加系统级函数
        if (this.applicationContext.getParent() == null) {
            list.add(new FlowableFunctionDelegate() {
                @Override
                public String prefix() {
                    return "";
                }

                @Override
                public String localName() {
                    return "asList";
                }

                @Override
                public Method functionMethod() {
                    return ClassUtils.getMethod(Arrays.class, "asList", Object[].class);
                }
            });
        }

        StringBuffer sb = new StringBuffer("注册" + this.applicationContext.getId()
                + ".flowable表达式函数:\n----------------------------------------------------------\n");
        Collection<FlowableFunctionDelegate> functions = this.applicationContext
                .getBeansOfType(FlowableFunctionDelegate.class).values();
        functions.forEach(fn -> {
            list.add(fn);
            for (String prefix : fn.prefixes()) {
                for (String localName : fn.localNames()) {
                    String pstr = "";
                    for (Parameter p : fn.functionMethod().getParameters()) {
                        if (pstr.length() > 0) {
                            pstr += ",";
                        }
                        pstr += p.toString();
                    }
                    sb.append(String.format("%s:%s(%s),", prefix, localName, pstr));
                }
            }
        });
        log.info("{}\n----------------------------------------------------------", sb.toString());

        springProcessEngineConfiguration.getExpressionManager().setFunctionDelegates(list);
    }
}
